package cell

import (
	"github.com/treelab/updatecolumn/models"
)

// InstanceType of cell
func InstanceType() int32 {
	return models.MultiAttachment
}


  CellMultiAttachment extends CellTransaction {
  get instanceType() {
    return ColumnType.MULTI_ATTACHMENT;
  }

  cellValueToString({ cell }: { cell: Cell }) {
    const values = cell.hasCellValue.get();
    return values.map(i => `${i.fileName} (${i.url})`).join(' ,');
  }

  convertCell(
    command: UpdateColumn_v2,
    o: CommonOptions,
    { columnCopy, referenceColumns }: { columnCopy: Column; referenceColumns?: Column[] },
  ) {
    const { column } = command;
    const { type: toType } = command.columnConfig;
    const cells = column.hasCell.get();
    const { columnType: fromType } = columnCopy;
    if (toType === fromType) {
      return this;
    }
    const events = new EventHelper();
    if (this.needEmptyCell(command)) {
      const fromCellHandle = this.instanceFactory.getCellInstance(fromType as ColumnType);
      fromCellHandle.emptyCells(command, cells, false, { ...o, events });
    }
    const visableNameMapping = new Map<string, string>();
    _.forEach(cells, cell => {
      const action = {
        type: UpdateAction.SET_VALUE,
        value: { ...command.columnConfig, type: toType },
      };
      const updateCell = {
        ...command,
        action,
        _metadata: { ...command._metadata, source: Source.SAGA },
      };
      const rowData = super.upsertCell(cell, { command: updateCell }, o);
      if (rowData) {
        visableNameMapping.set(rowData.uid, rowData.visibleName);
      }
    });
    this.updateReferenceColumnAndDependencies({
      column,
      visableNameMapping,
      o,
      _metadata: command._metadata,
      referenceColumns,
    });
    o.events.bulkAddEvents(...events);
    return this;
  }

  setCellValue({ cell, action, isNewCell }: ICCAction, o: CommonOptions) {
    const { delQuads } = o;
    const { value, type: actionType } = action;
    const fileAttachments = (value as MultiAttachmentCellValue).attachments!;
    if (actionType === UpdateAction.REMOVE_VALUE) {
      throw new CellValueError('Cannot use remove value for multi-attachment type');
    }
    // @TODO Judge existing values and delete only edges that don't really exist
    if (!isNewCell) {
      // if set value, remove all existing attachments first
      if (actionType === UpdateAction.SET_VALUE) {
        cell.hasCellValue
          .get()
          .forEach(attachment => delQuads.push(`<${cell.uid!}> <${Relation.HAS_CELL_VALUE}> <${attachment.uid}> .`));
      }
    }
    _.forEach(fileAttachments, (fileAttachment, order) =>
      this.createMultiAttachmentCellValueMutations(
        {
          cell,
          fileAttachment,
          order,
        },
        o,
      ),
    );
    return this;
  }

  getCellValue(cell: Cell | any) {
    return cell.values;
  }

  emptyCells(command: UpdateColumn_v2, cells: readonly Cell[], deleteCells: boolean, o: CommonOptions) {
    if (!deleteCells) {
      _.forEach(cells, cell => {
        if (cell.uid) {
          o.delQuads.push(...this.dgraphHelperService.getRemoveEdgeQuads(cell.uid, Relation.HAS_CELL_VALUE));
        }
      });
    }
    super.emptyCells(command, cells, deleteCells, o);
    return this;
  }

  private createMultiAttachmentCellValueMutations(
    { cell, fileAttachment, order }: { cell: Cell; fileAttachment: AttachmentInput; order: number },
    o: CommonOptions,
  ): CellValue {
    const att = o.ormTransaction.nodeFor(CellValue);
    att.url = escapeJS(fileAttachment.url);
    att.fileId = att.fileId;
    att.fileName = escapeJS(fileAttachment.fileName || '');
    att.fileType = fileAttachment.fileType || '';
    att.fileKey = fileAttachment.fileKey || '';
    att.fileSize = fileAttachment.fileSize || 0;
    att.smallThumbUrl = escapeJS(fileAttachment.smallThumbUrl || '');
    att.mediumThumbUrl = escapeJS(fileAttachment.mediumThumbUrl || '');
    att.largeThumbUrl = escapeJS(fileAttachment.largeThumbUrl || '');
    att.type = GraphNodeTypes.CELL_VALUE;
    cell.hasCellValue.withFacet(new OrderFacet({ order })).add(att);
    att.fromCell.add(cell);
    return att;
  }

